package com.jin.webvideo.config;

import com.jin.webvideo.base.spring.interceptor.InterceptorChain;
import com.jin.webvideo.base.spring.interceptor.LoginInterceptor;
import com.jin.webvideo.base.spring.resource.LinkedFileResourceHandlerRegistration;
import com.jin.webvideo.base.LoginHandler;
import com.jin.webvideo.base.spring.interceptor.PageMappingInterceptor;
import com.jin.webvideo.parser.ParserScriptPropertites;
import com.jin.webvideo.service.ConfigService;
import com.jin.webvideo.util.consts.ConfigConst;
import com.jin.webvideo.util.base.StringUtil;
import com.jin.webvideo.base.spring.resource.LinkedFileResource;
import com.jin.webvideo.videoCache.CachesPropertites;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;

import java.lang.reflect.Field;
import java.net.URI;
import java.util.List;
import java.util.Map;

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Autowired
    private CachesPropertites cachesPropertites;
    @Autowired
    private ParserScriptPropertites scriptPropertites;
    @Autowired
    private LoginHandler loginHandler;
    @Autowired
    private ConfigService configService;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 设置登录页面
        loginHandler.login("/login");
        // 设置验证码页面
        loginHandler.vCode("/user/vCode");
        // 设置登录操作
        loginHandler.loginAction("/user/login", "account", "password", null);
        // 设置默认登陆成功页面
        loginHandler.loginSuccess("/index");
        // 设置登出操作
        loginHandler.logoutAction("/user/logout");
        // 设置默认登出成功页面
        loginHandler.logoutSuccess("/index");

        LoginInterceptor interceptor = new LoginInterceptor(configService, loginHandler);
        // 设置不自动登录的路径
        interceptor.excludePathAutoLogin("/admin/**");

        InterceptorChain chain = new InterceptorChain();
        chain.add(new PageMappingInterceptor(configService));
        chain.add(interceptor);

        // 注册TestInterceptor拦截器
        InterceptorRegistration registration = registry.addInterceptor(chain);
        registration.addPathPatterns("/**"); //所有路径都被拦截
        registration.excludePathPatterns(    //添加不拦截路径
                "/frame/**",
                "/js/**",                    //js静态资源
                "/css/**",                   //css静态资源
                "/public/**",                //public静态资源
                "/script/**",                //script静态资源
                "/error/**"                  //错误页面静态资源
        );
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        // 设置脚本的映射路径
        registry.addResourceHandler(scriptPropertites.getMappingPath())
                .addResourceLocations(localPathFormat(scriptPropertites.getSrciptLocation()));
        // 设置本地缓存的映射路径
        registry.addResourceHandler(cachesPropertites.getPrefix()+"/**")
                .addResourceLocations(localPathFormat(cachesPropertites.getLocation()));

        List<ResourceHandlerRegistration> registrations = getResourceHandlerList(registry);
        if (registrations != null) {
            //
            Map<String, String> mapping = configService.configMapByGroupId(ConfigConst.LINKEDFILEMAPPING);
            for (String key : mapping.keySet()) {
                String val = mapping.get(key);
                registrations.add(createVResourceHandlerRegistration(val, false, key));
            }
        }

        // 首页的动态样式映射路径
        String mappingPath = configService.configByGroupIdAndAttrid(ConfigConst.FRAMEPAGE_CONFIG, ConfigConst.ATTR_CONFIG_MAPPINGPATH);
        String location =  configService.configByGroupIdAndAttrid(ConfigConst.FRAMEPAGE_CONFIG, ConfigConst.ATTR_CONFIG_LOCATION);
        if (StringUtil.isEmpty(mappingPath) || StringUtil.isEmpty(location)) {
            return;
        }
        registry.addResourceHandler(mappingPath)
                .addResourceLocations(localPathFormat(location));
    }

    private LinkedFileResourceHandlerRegistration createVResourceHandlerRegistration(String uri, boolean isFile, String... pathPatterns) {
        LinkedFileResourceHandlerRegistration r = new LinkedFileResourceHandlerRegistration(pathPatterns);
        r.addResourceLocations(new LinkedFileResource(isFile, URI.create(uri)));
        return r;
    }
    private List<ResourceHandlerRegistration> getResourceHandlerList(ResourceHandlerRegistry registry) {
        try {
            Field registrationsField = registry.getClass().getDeclaredField("registrations");
            registrationsField.setAccessible(true);
            List<ResourceHandlerRegistration> registrations = (List<ResourceHandlerRegistration>) registrationsField.get(registry);
            registrationsField.setAccessible(false);
            return registrations;
        }
        catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }
    private String localPathFormat(String path){
        return "file:" + path;
    }
}